package qhLoading.manager 
{
	import flash.display.*;
    import flash.events.*;
    import flash.net.*;
    import flash.system.*;
    import flash.utils.*;
	
	/**
	 * ...
	 * @author gcxk721
	 */
	public class CacheManager extends EventDispatcher 
	{
		
		private var _sharedObject:SharedObject;
        private const NeedSpace : int = 3.14573e+007;
        private var _versionData:Object;
        private var _memoryData:Object;
        private const CacheName:String = "xyfyCache";
        private const CachePath:String = "/xyfy/xyfyCache";
        private var _isCache:Boolean = false;
        private const Delay:int = 500;
        private var _saveTimer:Timer;
        private var _saveList:Array;
        private var localObject:Object;
        private const WriteConst:int = 100;
        private var _writeNum:int = 0;
        public var isAd:Boolean = false;
        private static var _instance:CacheManager;

        public function CacheManager()
        {
            this._versionData = {};
            this._memoryData = {};
            this._saveList = [];
        }

        public function get isCache() : Boolean
        {
            return this._isCache;
        }

        public function setLocalCache() : void
        {
            this.initCache();
            this.setCache(true);
        }

        private function setCache(value : Boolean) : void
        {
            var state:String;
            this.getSharedObject();
            if (this._sharedObject)
            {
                try
                {
                    this._sharedObject.addEventListener(NetStatusEvent.NET_STATUS, this.onNetStatusEvent);
                    state = this._sharedObject.flush(this.NeedSpace);
                    if (state != SharedObjectFlushStatus.PENDING)
                    {
                        this._sharedObject.data["isCache"] = true;
                        this._isCache = true;
                    }
                    else
                    {
                        this._sharedObject.data["isCache"] = false;
                        this._isCache = false;
                    }
                }
                catch (e:Error)
                {
                    _isCache = false;
                    Security.showSettings(SecurityPanel.LOCAL_STORAGE);
                }
            }
        }

        private function getSharedObject() : SharedObject
        {
            if (this._sharedObject == null)
            {
                try
                {
                    this._sharedObject = this.getLocal(this.CachePath);
                    this._versionData = this._sharedObject.data[this.CacheName];
                    this._isCache = this._sharedObject.data["isCache"];
                    this.isAd = this._sharedObject.data["isAd"];
                }
                catch (e:Error)
                {
                    _isCache = false;
                    isAd = false;
                }
                if (this._versionData == null)
                {
                    this._versionData = {};
                }
            }
            return this._sharedObject;
        }

        public function initCache() : void
        {
            /*if (this.localObject == null)
            {
                this.loadLocalObject();
            }*/
            if (this._saveTimer == null)
            {
                this._saveTimer = new Timer(this.Delay);
                this._saveTimer.addEventListener(TimerEvent.TIMER, this.onTimerHandler);
            }
        }

        public function initAd() : void
        {
            this.getSharedObject();
        }

        public function setAd() : void
        {
            this.isAd = true;
            if (this._sharedObject)
            {
                this._sharedObject.data["isAd"] = true;
                try
                {
                    this._sharedObject.flush();
                }
                catch (e:Error)
                {
                }
            }
        }

       /*private function loadLocalObject() : void
        {
            var _loc_1:* = this.localurl;
            var _loc_2:* = new Loader();
            _loc_2.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onLoadCompleteHandler);
            _loc_2.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, this.onErrorHandler);
            _loc_2.load(new URLRequest(_loc_1), new LoaderContext(false, new ApplicationDomain()));
        }*/

       /* private function onErrorHandler(event:IOErrorEvent) : void
        {
            var _loc_2:* = event.target as LoaderInfo;
            this.localObject = null;
            _loc_2.removeEventListener(Event.COMPLETE, this.onLoadCompleteHandler);
            _loc_2.removeEventListener(IOErrorEvent.IO_ERROR, this.onErrorHandler);
            this.getSharedObject();
        }*/

        /*private function onLoadCompleteHandler(event:Event) : void
        {
            var _loc_2:* = event.target as LoaderInfo;
            _loc_2.removeEventListener(Event.COMPLETE, this.onLoadCompleteHandler);
            _loc_2.removeEventListener(IOErrorEvent.IO_ERROR, this.onErrorHandler);
            this.localObject = _loc_2.content as Object;
            this.getSharedObject();
        }*/

        private function getLocal(name:String, localPath:String = null, secure:Boolean = false) : SharedObject
        {
            /*if (this.localObject)
            {
                return this.localObject.getLocal(param1, param2, param3);
            }*/
            return SharedObject.getLocal(name, localPath, secure);
        }

        private function onTimerHandler(event : TimerEvent) : void
        {
            var write : Object = null;
            if (this._saveList.length > 0)
            {
                write = this._saveList.shift();
                if (this.writeFile(write.n, write.data, write.path) == false)
                {
                    this.deleteVersion(write.n);
                }
                else
                {
                    this.setVersion(write.n, write.v);
                    _writeNum += 1;
                }
            }
            else if (this._saveTimer.running)
            {
                this._saveTimer.stop();
            }
        }

        private function setVersion(name : String, version:String) : void
        {
            this._versionData[name] = version;
            if (this._sharedObject)
            {
                this._sharedObject.data[this.CacheName] = this._versionData;
            }
        }

        private function getVersion(name : String) : String
        {
            return this._versionData[name];
        }

        private function deleteVersion(version:String) : void
        {
            delete this._versionData[version];
            if (this._sharedObject)
            {
                this._sharedObject.data[this.CacheName] = this._versionData;
            }
        }

        public function readObject(name : String, version:String, path:String = null) : Object
        {
            if (this._isCache)
            {
				var tVersion : String = getVersion(name);
                if (tVersion == version)
                {
                    return this.readFile(name, path);
                }
                return null;
            }
            return null;
        }

        public function writeObject(name:String, version:String, data:Object, path:String = null) : void
        {
            if (this._isCache)
            {
                this._saveList.push({n:name, v:version, data:data, path:path});
                this.startTimer();
            }
        }

        private function startTimer() : void
        {
            if (this._saveTimer.running == false)
            {
                this._saveTimer.start();
            }
        }

        private function writeMemory(key : String, value : Object) : void
        {
            this._memoryData[key] = value;
        }

        private function readMemory(key:String) : Object
        {
            return this._memoryData[key];
        }

        private function deleteMemory(key:String) : void
        {
            delete this._memoryData[key];
        }

        private function readFile(fileName:String, path:String = null) : Object
        {
            var so:SharedObject;
            var file:Object;
            if (path == null)
            {
                path = fileName;
            }
            try
            {
                so = this.getLocal(path);
                file = so.data[fileName];
                return file;
            }
            catch (e:Error)
            {
            }
            return null;
        }

        private function writeFile(fileName : String, file : Object, path : String = null) : Boolean
        {
            var so:SharedObject;
            if (file == null)
            {
                return false;
            }
            if (path == null)
            {
                path = fileName;
            }
            try
            {
                so = this.getLocal(path);
                so.data[fileName] = file;
                return true;
            }
            catch (e:Error)
            {
            }
            return false;
        }

        public function clear() : void
        {
            this._saveList.length = 0;
            this._memoryData = {};
            this._versionData = {};
            this._sharedObject.data[this.CacheName] = this._versionData;
            this._sharedObject.flush();
            this._saveTimer.stop();
        }

        private function onNetStatusEvent(event:NetStatusEvent) : void
        {
            if (event.info.code == "SharedObject.Flush.Failed")
            {
                this._isCache = false;
                this.clear();
            }
            else
            {
                this._sharedObject.removeEventListener(NetStatusEvent.NET_STATUS, this.onNetStatusEvent);
                this._isCache = true;
            }
            this._sharedObject.data["isCache"] = this._isCache;
        }

        public function flush() : void
        {
            if (this._isCache && this._writeNum > 0)
            {
                this._writeNum = 0;
                if (this._sharedObject)
                {
                    this._sharedObject.flush();
                }
            }
        }

        public static function get instance() : CacheManager
        {
            if (_instance == null)
            {
                _instance = new CacheManager;
            }
            return _instance;
        }
		
	}

}